import re


def contains(text: str):
    def _contains(line: str):
        return text in line

    return _contains


def startswith(prefix: str):
    def _startswith(line: str):
        return line.startswith(prefix)

    return _startswith


def endwith(suffix: str):
    def _endwith(line: str):
        return line.endswith(suffix)

    return _endwith


def oneof(*predicates):
    def _oneof(line: str):
        for predicate in predicates:
            if predicate(line):
                return True
        return False

    return _oneof


def allof(*predicates):
    def _allof(line: str):
        for predicate in predicates:
            if not predicate(line):
                return False
        return True

    return _allof


def re_match(pattern: str):
    def _match(line: str):
        return re.match(pattern, line) is not None

    return _match


def re_fullmatch(pattern: str):
    def _re_fullmatch(line: str):
        return re.fullmatch(pattern, line) is not None

    return _re_fullmatch


def re_search(pattern: str):
    def _re_search(line: str):
        return re.search(pattern, line) is not None

    return _re_search


def exactly(predicate: str):
    def _exactly(line: str):
        return line == predicate

    return _exactly


def is_not(predicate):
    def _is_not(line: str):
        return not predicate(line)

    return _is_not
